#include "DataCollector.h"
#include "protocols/ModbusHandler.h"
#include <fstream>
#include "include/nlohmann/json.hpp"
#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
#include <mutex>

// JSON库命名空间
using json = nlohmann::json;

namespace {
    // 数据保存路径（使用constexpr避免运行时计算）
    constexpr const char* DATA_OUTPUT_PATH = "/Users/hefeiyu/Downloads/智慧电厂SIS系统/src/前端/data.json";
    
    // 线程安全的计数器
    std::atomic<int> saveCounter{0};
    
    // 文件写入互斥锁
    std::mutex fileMutex;
}

// 数据转换函数
json convertPointsToJson(const std::vector<PointData>& points) {
    json j;
    try {
        // 使用毫秒级时间戳
        auto now = std::chrono::system_clock::now();
        j["timestamp"] = std::chrono::duration_cast<std::chrono::milliseconds>(
            now.time_since_epoch()).count();
        
        j["point_count"] = points.size();
        
        // 直接创建数组，不需要reserve()
        j["points"] = json::array();  // 这行可以省略，push_back会自动创建数组

        for (const auto& point : points) {
            json pointJson;
            pointJson["id"] = point.id;
            pointJson["name"] = point.name;
            pointJson["value"] = point.value;
            pointJson["unit"] = point.unit;
            pointJson["is_alarm"] = point.is_alarm;
            pointJson["timestamp"] = std::chrono::duration_cast<std::chrono::milliseconds>(
                point.timestamp.time_since_epoch()).count();
            
            j["points"].push_back(std::move(pointJson));
        }
    } catch (const std::exception& e) {
        std::cerr << "Error converting data to JSON: " << e.what() << std::endl;
    }
    return j;
}

// 数据回调函数
void dataCallback(const std::vector<PointData>& newData) {
    const int saveInterval = 10;
    
    if (++saveCounter % saveInterval != 0) {
        return;
    }

    try {
        json j = convertPointsToJson(newData);
        
        // 使用互斥锁保证线程安全的文件写入
        std::lock_guard<std::mutex> lock(fileMutex);
        
        std::ofstream outputFile(DATA_OUTPUT_PATH, std::ios::trunc);
        if (!outputFile) {
            throw std::runtime_error("Failed to open output file");
        }
        
        outputFile << j.dump(4);
        
    } catch (const std::exception& e) {
        std::cerr << "[" << __func__ << "] Error: " << e.what() << std::endl;
    }
}

int main() {
    std::cout << "=== 智慧电厂SIS系统 - 数据采集模块 ===\n";
    
    try {
        // 创建数据采集器（采集间隔100ms）
        DataCollector collector(std::chrono::milliseconds(100));

        // // 配置Modbus协议处理器
        // ModbusConfig modbusConfig = {
        //     "127.0.0.1",  // 实际设备IP地址
        //     502,                // Modbus默认端口
        //     1,              // 从站地址
        //     0,         // 起始寄存器地址
        //     200,      // 寄存器数量
        //     1000,         // 超时时间
        //     3                // 重试次数
        // };

        ModbusConfig modbusConfig;  // 使用默认构造函数初始化
        modbusConfig.ip_address = "127.0.0.1";  // 覆盖默认值
        modbusConfig.port = 502;
        modbusConfig.slave_id = 1;
        modbusConfig.start_address = 0;
        modbusConfig.register_count = 200;       // 修改默认的10
        modbusConfig.timeout_ms = 1000;
        modbusConfig.retries = 3;

        // 添加Modbus协议处理器
        auto modbusHandler = std::make_unique<ModbusHandler>(modbusConfig);
        if (!collector.addProtocolHandler(std::move(modbusHandler))) {
            throw std::runtime_error("Failed to add Modbus protocol handler");
        }

        // 设置数据回调函数
        collector.setDataCallback(dataCallback);

        // 启动数据采集
        if (!collector.startCollection()) {
            throw std::runtime_error("Failed to start data collection");
        }

        std::cout << "Data collection started successfully. Total points: " 
                  << collector.getTotalPoints() << "\n";
        std::cout << "Press Enter to stop...\n";

        // 等待用户输入停止
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

        // 停止数据采集
        collector.stopCollection();
        std::cout << "Data collection stopped.\n";

    } catch (const std::exception& e) {
        std::cerr << "[FATAL] " << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}